home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / std / c++ / 604 < prev    next >
Encoding:
Internet Message Format  |  1996-08-06  |  3.1 KB

  1. From: tony@online.tmx.com.au (Tony Cook)
  2. Message-ID: <199602292206.JAA27760@online.tmx.com.au>
  3. X-Original-Date: Fri, 1 Mar 1996 09:06:10 +1100
  4. Path: in1.uu.net!bounce-back
  5. Date: 01 Mar 96 14:55:27 GMT
  6. Approved: fjh@cs.mu.oz.au
  7. Newsgroups: comp.std.c++
  8. Subject: Re: operators new[]/delete[]
  9. Organization: Home
  10. References: <313166CF.11C2@orbotech.co.il> <4gu414$62u@mulga.cs.mu.OZ.AU> <4h24c2$pq@caesar.ultra.net>
  11. X-Newsreader: TIN [version 1.2 PL2]
  12. X-Auth: PGPMoose V1.1 PGP comp.std.c++
  13.     iQBFAgUBMTcP8OEDnX0m9pzZAQFzQAF/YFZdEaZ+yZiHKdYK5/71JRkiMyUxGy7g
  14.     3vHJc3sKpPyfyp40C409CNsZVnHGcScF
  15.     =2WE/
  16.  
  17. Pablo Halpern (phalpern@truffle.ultranet.com) wrote:
  18. : Although I don't agree with most of what Constantine Antonovich says, I
  19. : do wonder about one particular set of situations. Many allocation and
  20. : re-allocation systems use the default new() operator to allocate memory
  21. : in the form of char arrays. This "raw" memory is then recast to an array
  22. : of specific type, which is initialized one element at a time:
  23.  
  24. :   template <class T>
  25. :   T* dup_array(const T* p, size_t s)
  26. :   {
  27. :     T *p2 = reinterpret_cast<T*> new char[s * sizeof(T)];  // note 1
  28. :     while (s-- > 0)
  29. :       new (p2 + s) T(p[s]);  // Initialize using copy constructor
  30. :   }
  31.  
  32. :   void f(T* p, size_t s)
  33. :   {
  34. :     T* newp = dup_array(p, s);
  35. :     // do something with newp
  36. :     delete [] newp;     // note 2
  37. :   }
  38.  
  39. : I believe that something similar to the line marked "note 1" is common
  40. : practice for this sort of operation. However, I believe that the line
  41. : marked "note 2" is undefined behavior. 
  42.  
  43. Yes it is.
  44.  
  45. : Is there a way in the standard
  46. : can be modified so that the above code becomes well-defined and works as
  47. : intended? 
  48.  
  49. This isn't likely - most delete[] implementations where a
  50. non-trivial destructor is involved will use extra information before
  51. the beginning of the array - which isn't present in your example
  52. (and that information is implementation dependent, so you can't set
  53. it portably in your own code).
  54.  
  55. : How does the STL deal with this in its "unitialized copy"
  56. : operation?
  57.  
  58. It destroys the original objects using their destructors (and the
  59. containers call operator delete to release the memory.)
  60.  
  61. For example:
  62.    template <class T>
  63.    void f(const T* p, size_t s)
  64.    {
  65.      p += s;
  66.      while (s-- > 0)
  67.        (--p)->~T();
  68.      operator delete(p);
  69.    }
  70.  
  71.  
  72. : There is another way to allocate raw memory, but here the operations are
  73. : even less defined (I believe):
  74.  
  75. :    void *p2 = operator new[] (s * sizeof(T));
  76. :    delete p2;  // What does this do? p2 was not the result of a normal
  77. :                // new expression.
  78. :    delete reinterpret_cast<T*> p2;  // What does this do?
  79.  
  80. You should use:
  81.     operator delete[](p2);
  82.  
  83. -- 
  84.         Tony Cook - tony@online.tmx.com.au
  85.                     100237.3425@compuserve.com
  86. ---
  87. [ To submit articles: try just posting with your news-reader.
  88.                       If that fails, use mailto:std-c++@ncar.ucar.edu
  89.   FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html
  90.   Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html
  91.   Comments? mailto:std-c++-request@ncar.ucar.edu.
  92. ]
  93.